
#include <BLabel>
#include <BGridLayout>
#include <BVBoxLayout>
#include <BHBoxLayout>
#include <BStyle>
#include <BPainter>
#include <BStyle>
#include <BFont>
#include <BStackLayout>

#include "HingeRestraintPanel.h"
#include "PointRestraintPanel.h"
#include "SliderRestraintPanel.h"
#include "ConearRestraintPanel.h"
#include "SixdofRestraintPanel.h"
#include "FixedRestraintPanel.h"
#include "GearRestraintPanel.h"
#include "RestraintBoard.h"

RestraintBoard::RestraintBoard(BWidget* parent) : BGroupBox(parent)
{
	this->setTitle("BRestraint");
	this->setTitleAlign(Align_Center);

	BHBoxLayout* titleLayout = new BHBoxLayout();
	{
		_foldeButton = new BButton();
		_foldeButton->setCheckable(true);
		_foldeButton->setAlign(Align_Center);
		_foldeButton->setForm(Form_IconAlone);
		_foldeButton->setGraph(Graph_Minus);
		_foldeButton->setIconSize(12);
		_foldeButton->setFixedSize(16);

		titleLayout->addWidget(_foldeButton);
		titleLayout->addSpring();
		titleLayout->setMargin(5);
	}
	this->setLayout(titleLayout, Part_Top);

	BGridLayout* gridLayout = new BGridLayout();
	{
		BLabel* nameLabel = new BLabel("Name");
		_nameEdit = new BLineEdit();

		BLabel* enabledLabel = new BLabel("Enabled");
		_enabledCheckBox = new BCheckBox();

		BLabel* innerCollibleLabel = new BLabel("Inner Collible");
		_collidingCheckBox = new BCheckBox();

		BLabel* breakImpulseLabel = new BLabel("Break Impulse");
		_breakImpulseSpinBox = new BRealSpinBox();

		gridLayout->addWidget(0, 0, nameLabel);
		gridLayout->addWidget(0, 1, _nameEdit);
		gridLayout->addWidget(1, 0, enabledLabel);
		gridLayout->addWidget(1, 1, _enabledCheckBox);
		gridLayout->addWidget(2, 0, innerCollibleLabel);
		gridLayout->addWidget(2, 1, _collidingCheckBox);
		gridLayout->addWidget(3, 0, breakImpulseLabel);
		gridLayout->addWidget(3, 1, _breakImpulseSpinBox);
	}

	BStackLayout* stackLayout = new BStackLayout("stack");
	stackLayout->addWidget(new PointRestraintPanel);
	stackLayout->addWidget(new HingeRestraintPanel);
	stackLayout->addWidget(new SliderRestraintPanel);
	stackLayout->addWidget(new ConearRestraintPanel);
	stackLayout->addWidget(new SixdofRestraintPanel);
	stackLayout->addWidget(new FixedRestraintPanel);
	stackLayout->addWidget(new GearRestraintPanel);

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(gridLayout);
	vlayout->addLayout(stackLayout);

	connect(this, Signal_AssetChanged, &RestraintBoard::slotAssetChanged);
	connect(_foldeButton, Signal_Checked, &RestraintBoard::slotFoldeButtonChecked);
	connect(_nameEdit, Signal_EditFinished, &RestraintBoard::slotNameEditFinished);
	connect(_enabledCheckBox, Signal_Toggled, &RestraintBoard::slotEnabledBoxToggled);
	connect(_collidingCheckBox, Signal_Toggled, &RestraintBoard::slotInnerCollibleToggled);
	connect(_breakImpulseSpinBox, Signal_EditFinished, &RestraintBoard::slotBreakImpulseEditFinished);
}
RestraintBoard::~RestraintBoard()
{

}

void RestraintBoard::slotAssetChanged(const BObject* object, const BValue& value)
{
	BStackLayout* stackLayout = (BStackLayout*)this->layout("stack");
	if (BRestraint* restraint = value)
	{
		this->setTitle(restraint->className());
		_nameEdit->setText(restraint->name());
		_enabledCheckBox->setChecked(restraint->enabled());
		_collidingCheckBox->setChecked(restraint->colliding());
		_breakImpulseSpinBox->setValue(restraint->breakImpulse());
		for (int i = 0; i < stackLayout->count(); i++)
		{
			BWidget* widget = stackLayout->widget(i);
			if (!widget)
				continue;
			if (widget->title() == restraint->className())
			{
				widget->setAsset(restraint);
				stackLayout->setCurrent(widget);
				break;
			}
		}
		this->adjust();
		this->setEnabled(true);
	}
	else
	{
		this->setTitle(BString());
		stackLayout->setCurrent(0);
		this->setEnabled(false);
	}
	this->setVisible(value.valid());
}
void RestraintBoard::slotFoldeButtonChecked(const BObject* object, const BValue& value)
{
	bool checked = value;
	if (checked)
		_foldeButton->setGraph(Graph_Plus);
	else
		_foldeButton->setGraph(Graph_Minus);
	this->setFolded(checked);
}
void RestraintBoard::slotNameEditFinished(const BObject* object, const BValue& value)
{
	if (BRestraint* restraint = this->asset())
	{
		const BString& name = value;
		restraint->setName(name);
	}
}
void RestraintBoard::slotEnabledBoxToggled(const BObject* object, const BValue& value)
{
	if (BRestraint* restraint = this->asset())
	{
		bool enabled = value;
		restraint->setEnabled(enabled);
	}
}
void RestraintBoard::slotInnerCollibleToggled(const BObject* object, const BValue& value)
{
	if (BRestraint* restraint = this->asset())
	{
		bool checked = value;
		restraint->setColliding(checked);
	}
}
void RestraintBoard::slotBreakImpulseEditFinished(const BObject* object, const BValue& value)
{
	if (BRestraint* restraint = this->asset())
	{
		BReal breakImpulse = value;
		restraint->setBreakImpulse(breakImpulse);
	}
}
